/**
 * @fileoverview js.io.Serializer class {@link http://jsvm.org/}
 * @file		Serializer.js
 * @author	Wan Changhua
 * @version	2.01, 10/23/05
 * @since		JSVM1.0
 */

/**
 * Create a new Serializer instance.
 * Inherit from JObject
 * @author	Wan Changhua
 * @version	2.01, 10/23/05
 * @extends js.lang.JObject
 * @class js.io.Serializer is a utility class for serialize
 * @constructor
 * @final
 */
function Serializer() {}

/**
 * serialize an object to string
 * @param {Object} obj an object to be serialized.
 * @return the result of serialized object
 * @type String
 */
Serializer.serialize = function(obj)
{
	var sb = [];
	switch (typeof obj)
	{
		case "object" :
			if (null == obj)
			{
				sb.push("null");
			}
			else if (typeof obj.serialize == "function")
			{
				sb.push(obj.serialize());
			}
			else if (obj instanceof Array)
			{
				sb.push("[");
				var astr = [];
				for (var i = 0;i < obj.length; i++)
				{
					astr[i] = Serializer.serialize(obj[i]);
				}
				sb.push(astr.join(","));
				sb.push("]");
			}
			else
			{
				sb.push("{");
				var nc = false;
				for (var name in obj)
				{
					var value = obj[name];
					var type = typeof(value);
					if (type != "undefined" && type != "function")
					{
						if (nc)
						{
							sb.push(",");
						}
						else
						{
							nc = true;
						}
						sb.push(Serializer.serialize(name));
						sb.push(":");
						sb.push(Serializer.serialize(value));
					}
				}
				sb.push("}");
			}
			break;
		case "boolean" :
			sb.push(obj.toString());
			break;
		case "number" :
			sb.push(isFinite(obj) ? String(obj) : "null");
			break;
		case "string" :
			sb.push('"');
			var l = obj.length;
			for (i = 0; i < l; i++)
			{
				var c = obj.charAt(i);
				if (c >= " ")
				{
					if (c == "\\" || c == '"')
					{
						sb.push("\\");
					}
					sb.push(c);
				}
				else
				{
					switch (c){
						case "\b" :
							sb.push("\\b");
							break;
						case "\f" :
							sb.push("\\f");
							break;
						case "\n" : 
							sb.push("\\n");
							break;
						case "\r" : 
							sb.push("\\r");
							break;
						case "\t" : 
							sb.push("\\t");
							break;
						default:
							sb.push("\\u00");
							sb.push(c.charCodeAt().toString(16));
					}
				}
			}
			sb.push('"');
			break;
		default : 
			sb.push("null"); 
			break;
	}
	return sb.join("");
}

/**
 * unserialize a string to object
 * @param {String} str a string
 * @return an object
 * @type Object
 */
Serializer.unserialize = function(str)
{
	return eval(str);
}